home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
FM Towns: Free Software Collection 4
/
FM Towns Free Software Collection 4 - Disc 1.iso
/
t_os
/
wstype
/
source
/
dropdm.c
< prev
next >
Wrap
C/C++ Source or Header
|
1991-10-18
|
4KB
|
174 lines
/*** [dropdm.c]
*
* ドロップダウンメニュー 関連 (C)ささがわ
*
* For GNU C Compiler (GCC) Version 1.39
*
***/
#include <stdio.h>
#include <string.h>
#include "dropdm.h"
#include "graph.h"
#include "mos.h"
#include "others.h"
extern int PAL_Black, PAL_Button;
static int Title, nTitle, nMenu, Shadow;
static int Yt1, Yt2, Xm1, Xm2, Ym1, Ym2;
static struct menu_t *Menu;
static int DRPDM_sub(int *);
static void Rev_sub(int);
static void Open(void);
static void Close(void);
static int Where(int, int, int *);
static int Where_title(int, int);
/**
* ドロップダウンメニュー 関数
* 入力: x, y 呼び出し直前のマウス座標, dp パラメータ
* 出力: 戻り値が真の場合 メニューが選択されたことを示す
* x タイトル番号, y メニュー番号 (戻り値が偽の場合は不定)
**/
int DRPDM_main(int *x, int *y, struct dropdm_t *dp) {
int t, p, mx, my;
char mb;
nTitle = dp->ntitle; Yt1 = dp->yt1;
Yt2 = dp->yt2; Ym1 = dp->ym;
Menu = dp->m; Shadow = dp->shadow;
if ((t = Where_title(*x, *y)) < 0)
return 0;
do p = t; while (!DRPDM_sub(&t));
while (MOS_rdpos(&mb, &mx, &my), mb & 1);
*x = p; *y = t;
return (t < 0 ? 0 : 1);
}
/* 入力: t タイトル番号
出力: 戻り値が正の場合 メニューが選択され t にその番号が返される
〃 零の場合 タイトルが選択され t に 〃
〃 負の場合 上記以外が選択されたことを示す t は負
*/
static int DRPDM_sub(int *t) {
int flag = -1, lop = 1;
int mx, my, rel, fwh, wh;
char mb;
Title = *t;
for (nMenu = 0; Menu[Title].name[nMenu] != NULL; nMenu++);
Xm1 = Menu[Title].xm;
Xm2 = Xm1 + Menu[Title].wm * 8 - 1;
Ym2 = Ym1 + nMenu * 20 - 1;
Open();
MOS_rdpos(&mb, &mx, &my);
rel = mb & 1 ? 0 : 1;
do {
int a;
do {
CLOCK(0);
MOS_rdpos(&mb, &mx, &my);
} while (!(mb & 1) && rel);
fwh = Where(mx, my, &wh);
a = fwh > 0 && wh >= 0 ? wh : -1;
if (flag != a) {
Rev_sub(flag); Rev_sub(a);
flag = a;
}
if (mb & 1) {
if (rel && fwh < 0 || !fwh)
lop = 0;
rel = 0;
} else {
if (fwh <= 0 || wh >= 0) /* !(fwh > 0 && wh < 0) */
lop = 0;
rel = 1;
}
} while (lop);
Close();
*t = !fwh ? wh : flag;
return fwh;
}
static void Rev_sub(int i) {
int a;
if (i < 0)
return;
a = Ym1 + 20 * i;
EGB_rev(1, Xm1, a, Xm2, a + 19);
}
static void Open(void) {
int i;
struct menu_t *p = Menu + Title;
MOS_disp(0);
EGB_rev(0, p->xt, Yt1, p->xt + p->wt - 1, Yt2);
EGB_mycopy(EGB_readactPage(), Xm1 - 1, Ym1 - 1, Xm2 + 3, Ym2 + 3, 0, 650, 0);
if (Shadow) {
EGB_boxf(Xm2 + 2, Ym1 + 1, Xm2 + 3, Ym2 + 3, PAL_Black, PAL_Black);
EGB_boxf(Xm1 + 1, Ym2 + 2, Xm2 + 3, Ym2 + 3, PAL_Black, PAL_Black);
}
EGB_boxf(Xm1 - 1, Ym1 - 1, Xm2 + 1, Ym2 + 1, PAL_Black, 15);
for (i = 0; i < nMenu; i++)
EGB_str2(p->name[i], Xm1, Ym1 + i * 20 + 17, p->mask[i] ? PAL_Button : PAL_Black);
MOS_disp(1);
}
static void Close(void) {
MOS_disp(0);
EGB_mycopy(0, 650, 0, 650 + Xm2 - Xm1 + 4, Ym2 - Ym1 + 4, EGB_readactPage(), Xm1 - 1, Ym1 - 1);
EGB_rev(0, Menu[Title].xt, Yt1, Menu[Title].xt + Menu[Title].wt - 1, Yt2);
MOS_disp(1);
}
static int Where(int x, int y, int *wh) {
int i, ret = -1;
if (Xm1 <= x && x <= Xm2 && Ym1 <= y && y <= Ym2) {
struct menu_t *p;
*wh = (y - Ym1) / 20;
p = Menu + Title;
if (!strncmp(p->name[*wh] + 1, "─", 2) || p->mask[*wh]) *wh = -1;
ret = 1;
} else if ((i = Where_title(x, y)) >= 0) {
if (i == Title) {
*wh = -1; ret = 1;
} else {
*wh = i; ret = 0;
}
}
return ret;
}
static int Where_title(int x, int y) {
int i, ret = -1;
struct menu_t *p;
for (i = 0, p = Menu; i < nTitle; i++, p++) {
if (p->xt <= x && x <= p->xt + p->wt - 1 && Yt1 <= y && y <= Yt2) {
ret = i;
break;
}
}
return ret;
}